#!/usr/bin/env python
# -*- coding:utf-8 -*-
import json
from os import path,sep
from json import loads
from re import search,I
from lib.utils.params import *
from lib.utils.printer import *
from lib.utils.readfile import *
from lib.request.request import *
from lib.utils.settings import ERRORS_PATH
class bufferoverflow(Request):
    """
    缓冲区溢出检测
    Buffer Overflow
    """
    get = "GET"
    post = "POST"
    def __init__(self,kwargs,url,data):
        Request.__init__(self,kwargs)
        self.url = url
        self.data = data
        self.result = {
            'bufferoverflow':None
        }
    def serror(self,resp):
        _ = None
        realpath = ERRORS_PATH
        abspath = realpath + sep + "buffer.json"
        _ = self.search(resp,json.loads(readfile(abspath)[0],encoding="utf-8"))
        if _ != None: return _
    def search(self,resp,content):
        for error in content['info']['regexp']:
            if search(error,resp):
                _ = content['info']['name']
                return _
    
    def check(self):
        info("检测缓冲区溢出漏洞...")
        URL = None
        DATA = None
        PAYLOAD = None
        char = ['A',"%00","%06x","0x0"]#用于溢出的字符
        isNothing = True
        for payload in char:
            for num in [10,100,200]:
                if self.data:
                    rPayload = preplace(self.url,(payload*num),self.data)
                    for data in rPayload.run():
                        more("检测载荷:{},{}".format(self.url,data))
                        req = self.Send(url=self.url,method=self.post,data=data)
                        error = self.serror(req.content)
                        if error:
                            URL = req.url
                            DATA = self.data
                            PAYLOAD = "{} * {}".format(payload,num)
                            break
                else:
                    urls = preplace(self.url,(payload*num),None)
                    for url in urls.run():
                        more("检测载荷:{}".format(url))
                        req = self.Send(url=url,method=self.get)
                        error = self.serror(req.content)
                        if error:
                            URL = url
                            PAYLOAD = "{} * {}".format(payload,num)
                            break
                if URL and PAYLOAD:
                    if DATA != None:
                        plus("疑似缓冲区漏洞被找到...")
                        more("URL[地址]: {}".format(URL))
                        more("POST DATA[数据]: {}".format(DATA))
                        more("PAYLOAD[有效载荷]: {}".format(PAYLOAD))
                        self.result['bufferoverflow'] = PAYLOAD
                        isNothing = False
                    elif DATA == None:
                        plus("疑似缓冲区漏洞被找到...")
                        more("URL[地址]: {}".format(URL))
                        more("PAYLOAD[有效载荷]: {}".format(PAYLOAD))
                        self.result['bufferoverflow'] = PAYLOAD
                        isNothing = False
                    break
        if isNothing:
            info_nothing()
        return self.result
def run(kwargs,url,data):
    result = {}
    scan = bufferoverflow(kwargs,url,data)
    result = scan.check()
    return result
